package uscdb.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import uscdb.dao.ReviewDaoI;
import uscdb.dao.UserDaoI;
import uscdb.dao.UserreviewDaoI;
import uscdb.model.Treview;
import uscdb.model.Tuser;
import uscdb.model.Tusertreview;
import uscdb.pageModel.DataGrid;
import uscdb.pageModel.PageHelper;
import uscdb.pageModel.Review;
import uscdb.service.ReviewServiceI;
import uscdb.util.RarUtil;
import uscdb.util.StringUtil.StringUtil;
import uscdb.util.poi.leoUtil;

@Service
public class ReviewServiceImpl implements ReviewServiceI {

	private static final Logger logger = Logger.getLogger(ReviewServiceImpl.class);

	private final int SIDCOLUMN = 0;
	private final int OWNERCOLUMN = 11;

	@Autowired
	private ReviewDaoI reviewDao;

	@Autowired
	private UserDaoI userDao;

	@Autowired
	private UserreviewDaoI userreviewDao;

	@Override
	public DataGrid dataGrid(Review review, PageHelper ph) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<String, Integer> reviewChart(String number) {
		// 给number一个初始值
		int pageNum = 30;
		if (!StringUtil.isEmpty(number)) {
			pageNum = Integer.valueOf(pageNum);
		}
		Map<String, Integer> reviewMap = new HashMap<>();
		Map<String, Object> params = new HashMap<>();
		String hql = "from Treview t ";
		// 获取前 number 条记录 降序
		PageHelper ph = new PageHelper(1, pageNum, "totalNum", "desc");
		List<Treview> treviewList = reviewDao.find(hql + orderHql(ph), params, ph.getPage(), ph.getRows());
		for (Treview t : treviewList) {
			reviewMap.put(t.getName(), t.getTotalNum());
		}
		return reviewMap;
	}

	@Override
	public Map<String, Float> peopleReviewChart(String number) {
		// 给number一个初始值
		int pageNum = 30;
		if (!StringUtil.isEmpty(number)) {
			pageNum = Integer.valueOf(pageNum);
		}

		Map<String, Float> peopleReviewMap = new HashMap<>();
		Map<String, Object> params = new HashMap<>();
		String hql = "from Tuser t ";
		// 获取前 number 条记录 降序
		PageHelper ph = new PageHelper(1, pageNum, "totalReviewNum", "desc");
		float average = 0;
		List<Tuser> tuserList = userDao.find(hql + orderHql(ph), params, ph.getPage(), ph.getRows());
		for (Tuser tuser : tuserList) {
			int times = 0;
			Set<Tusertreview> tusertreviewSet = tuser.getTusertreviewSet();
			for (Tusertreview tur : tusertreviewSet) {
				times += tur.getTimes();
			}
			if (times != 0) {
				average = tuser.getTotalReviewNum() / times;
			} else {
				average = tuser.getTotalReviewNum();
			}
			if (null != tuser.getName()) {
				peopleReviewMap.put(tuser.getName(), average);
			} else {
				peopleReviewMap.put(tuser.getSid(), average);
			}

		}
		return peopleReviewMap;
	}

	@Override
	public String importReviewTask(File file) {
		String resultString = "没有review文件";
		String regEx = "^ReviewReport.*";
		Pattern pattern = Pattern.compile(regEx);
		try {
			String reviewParentPath = file.getParent();
			if (RarUtil.untar(file, reviewParentPath)) {
				// 当前解压缩目录的路径
				String reviewPath = reviewParentPath + "/" + file.getName().substring(0, file.getName().length() - 4);
				// 进入加压缩目录里面寻找review excel的路径
				String reviewDirPath = findReviewFileParentPath(new File(reviewPath));
				File reviewExcelDir = new File(reviewDirPath);
				// 对review excel的处理，可能有多个
				for (String reviewFileString : reviewExcelDir.list()) {
					// 如果文件名前缀符合要求
					java.util.regex.Matcher matcher = pattern.matcher(reviewFileString);
					if (matcher.matches()) {
						Boolean analyseResult = analyseReviewExcel(new File(reviewDirPath + "/" + reviewFileString),
								file.getName());
						if (analyseResult) {
							resultString = "分析review数据成功";
						} else {
							resultString = "分析review数据失败";
						}
					}
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return resultString;
	}

	/**
	 * 功能：把review的excel数据分拆数据
	 * 
	 * @param reviewFile
	 *            review的File对象
	 * @return
	 */
	private Boolean analyseReviewExcel(File reviewFile, String tasknName) {
		// 最终的处理结果
		Boolean result = false;
		Review review = new Review();
		// 特性名通过读取rar文件获取
		String reviewName = reviewFile.getName()+"-"+tasknName;
		// review 的 owner
		String reviewOwnerSid = "";
		Treview treview = reviewDao.getByName(reviewName);
		if (null == treview) {
			// 如果是新的review，则创建
			treview = new Treview(UUID.randomUUID().toString(), reviewName, review.getScriptType(), 1);
			reviewDao.save(treview);
		} else {
			// 如果已经存在，则是重复上传，则上传次数+1,以防造假
			treview.setTimes(treview.getTimes() + 1);
		}
		try {
			FileInputStream fileStream = new FileInputStream(reviewFile);
			Workbook book = WorkbookFactory.create(fileStream);
			// 第3张表才是review的详细信息
			Sheet sheet = book.getSheetAt(2);

			// 如果曾经增加过tusertreview的次数，则存放在SET，避免重复增加
			Set<String> sidSet = new HashSet<>();
			for (int i = 2; i <= sheet.getLastRowNum(); i++) {
				// 查询出一次，代表有一条评审记录
				treview.setTotalNum(treview.getTotalNum() + 1);
				Row ros = sheet.getRow(i);
				// 读出工号
				String sid = leoUtil.ConvertCellToStr(ros.getCell(SIDCOLUMN));
				// L行是回复者，判断这个就是评审review的发起人
				reviewOwnerSid = leoUtil.ConvertCellToStr(ros.getCell(OWNERCOLUMN));
				if (!StringUtil.isEmpty(reviewOwnerSid)) {
					// 当有工号，才赋值
					treview.setReviewOwner(reviewOwnerSid);
				}
				// 根据工号找到人
				Tuser tuser = userDao.getBySid(sid);
				if (null == tuser) {
					// 如果是新的工号，则注册一个员工，并且评审数为1
					tuser = new Tuser(UUID.randomUUID().toString(), sid, 1);
					linkTuserAndTreview(tuser, treview);// 关联 user 与 review
					// 将已经处理过的员工保存起来，免得二次添加
					sidSet.add(sid);
				} else {
					// 不是新的员工，则+1
					tuser.setTotalReviewNum(tuser.getTotalReviewNum() + 1);
					// 如果已经关联，那就跳过，如果还没关联，那就关联
					Set<Tusertreview> tusertreviewSet = tuser.getTusertreviewSet();
					// 如果存在记录，则正常操作；如果不存在记录，则表示从未评审过
					if (null != tusertreviewSet && tusertreviewSet.size() != 0) {
						// 标记是否找到正确的treview
						Boolean turFlag = false;
						for (Tusertreview tur : tusertreviewSet) {
							// 如果存在记录，则对比是否曾经评审过该review
							if (null != tur.getTreview()) {
								if (treview.getName().equals(tur.getTreview().getName())) {
									// 找到记录，turFlag就要为真；如果sid集合不包含，则相应记录+1
									if (!sidSet.contains(sid)) {
										tur.setTimes(tur.getTimes() + 1);
										sidSet.add(sid);
									}
									turFlag = true;
									break;
								}
							}

						}
						// 如果没找到评审记录，那就新建一条
						if (!turFlag) {
							// 关联 user 与 review
							linkTuserAndTreview(tuser, treview);
							sidSet.add(sid);
						}
					} else {
						linkTuserAndTreview(tuser, treview);// 关联 user 与 review
						sidSet.add(sid);
					}
				}
			}
			// 只有最后全部处理完，result才能够等于true
			result = true;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return result;
	}

	/**
	 * 功能：关联tuser与treview
	 * 
	 * @param tuser
	 * @param treview
	 */
	private void linkTuserAndTreview(Tuser tuser, Treview treview) {
		Set<Tusertreview> tutrSet = new HashSet<>();
		Tusertreview tusertreview = new Tusertreview(UUID.randomUUID().toString(), tuser, treview, 1);
		tutrSet.add(tusertreview);
		tuser.setTusertreviewSet(tutrSet);
		treview.setTusertreviewSet(tutrSet);
		userreviewDao.save(tusertreview);
	}

	/**
	 * 功能：找到review文件所在文件夹的目录
	 * 
	 * @param file
	 *            当前文件
	 * @return
	 */
	public String findReviewFileParentPath(File file) {
		String fileCurrentPath = file.getParent() + "/" + file.getName();
		File currentDir = new File(fileCurrentPath);
		String finallReviewPath = "";
		for (String fileName : currentDir.list()) {
			File tmpFile = new File(fileCurrentPath + "/" + fileName);
			// 当名字为05.ReviewResult且是目录，返回当前的目录，即05.ReviewResult的父目录
			if (tmpFile.isDirectory()) {
				if (fileName.equals("05.ReviewResult")) {
					return fileCurrentPath + "/" + fileName;
				}
				// 当路径下的是目录，但名字不符合，继续迭代这个目录里面的内容
				finallReviewPath += findReviewFileParentPath(tmpFile);
				// 如果找到一个，那就终止迭代，返回现在的路径,防止多个相同名字的文件夹干扰
				if (!StringUtil.isEmpty(finallReviewPath)) {
					return finallReviewPath;
				}
			}
		}
		// 如果全部都没找到，返回空
		return finallReviewPath;
	}

	/**
	 * 排序函数
	 * 
	 * @param ph
	 *            分页对象
	 * @return
	 */
	private String orderHql(PageHelper ph) {
		String orderString = "";
		if (ph.getSort() != null && ph.getOrder() != null) {
			orderString = " order by t." + ph.getSort() + " " + ph.getOrder();
		}
		return orderString;
	}
}
